import { useState, useRef, useMemo, useImperativeHandle, useEffect } from 'react';
import { Button, Col, DatePicker, Form, Input, Row, Select, Space, TreeSelect } from 'antd';
import { DownCircleFilled, UpCircleFilled } from '@ant-design/icons';
import { useDataContext } from '../context';
import { SearchStyle } from './style';
import { formatDateWithZero } from '@/utils';
import type { MainTableProps, SearchItemType } from '../type';

const specialType: SearchItemType[] = ['DateRangePicker', 'DatePicker', 'TimePicker'];
const FormRowHeight = 56;
const FormItemRulesHeight = 24;
const SearchForm = <SearchType extends object>(
	props: Required<Pick<MainTableProps, 'search' | 'formRef' | 'onSearchFormChange' | 'formConfig'>>
) => {
	const { search, formRef, formConfig, onSearchFormChange } = props;
	const { tableListRef, setParamAction, setTableHeightAction } = useDataContext();

	const [form] = Form.useForm<SearchType>();
	const [open, setOpen] = useState(false);
	const height = useRef<number | null>(
		search?.length > 8 ? FormRowHeight * 2 + FormItemRulesHeight : null
	);

	const boxRef = useRef<HTMLDivElement>();

	const speNames = useMemo(
		() => search?.filter((item) => specialType.includes(item.component)) ?? [],
		[search]
	);

	// 搜索
	const handleSearch = () => {
		const params = form.getFieldsValue();
		for (const item of speNames) {
			if (params[item.name]) {
				if (item.component === 'DatePicker') {
					params[item.name] = formatDateWithZero(params[item.name]);
				} else if (item.component === 'DateRangePicker') {
					params[item.startKeyName ?? 'startDate'] = formatDateWithZero(params[item.name][0]);
					params[item.endKeyName ?? 'endDate'] = formatDateWithZero(params[item.name][1]);
					delete params[item.name];
				}
			}
		}
		tableListRef.current.isPageChange = false;
		onSearchFormChange?.(params);
		setParamAction(params, 'search');
	};

	// 重置
	const handleReset = () => {
		tableListRef.current.isPageChange = false;
		form.resetFields();
		onSearchFormChange?.({} as SearchType);
		setParamAction({}, 'reset');
	};

	// search的node节点
	const searchNode = useMemo(
		() =>
			search?.map((item, index) => {
				let node = null;
				switch (item.component) {
					case 'Select':
						node = (
							<Select
								allowClear
								placeholder="请选择"
								options={item.enum}
								style={{ width: '100%' }}
							/>
						);
						break;
					case 'DatePicker':
						node = <DatePicker allowClear style={{ width: '100%' }} />;
						break;
					case 'DateRangePicker':
						node = <DatePicker.RangePicker allowClear />;
						break;
					case 'TreeSelect':
						node = <TreeSelect allowClear placeholder="请选择" treeData={item.treeData} />;
						break;
					default:
						node = <Input allowClear placeholder="请输入" />;
				}
				return (
					<Col key={item.name + index} md={12} lg={8} xl={6}>
						<Form.Item label={item.label} name={item.name}>
							{node}
						</Form.Item>
					</Col>
				);
			}),
		[search]
	);

	// 监听dom元素变化
	useEffect(() => {
		setTableHeightAction(boxRef.current.clientHeight);
		const MutationObserver = window.MutationObserver;
		const observer = new MutationObserver((mutations) => {
			console.log(mutations, boxRef.current.clientHeight);
			setTableHeightAction(boxRef.current.clientHeight);
		});
		observer.observe(boxRef.current, {
			attributes: true,
			childList: true,
			attributeFilter: ['box_height']
		});
	}, []);

	useImperativeHandle(formRef, () => ({ ...form }));

	return (
		<SearchStyle ref={boxRef} box_height={height.current}>
			<div className="form-box">
				<Form form={form} labelCol={{ style: { width: `${formConfig?.labelWidth ?? 80}px` } }}>
					<Row>{searchNode}</Row>
				</Form>
			</div>
			<div className="search-btn">
				<div className="divider"></div>
				<div className="btns">
					<Space>
						<Button type="primary" onClick={handleSearch}>
							搜索
						</Button>
						<Button type="primary" ghost onClick={handleReset}>
							重置
						</Button>
					</Space>
					{search?.length > 8 && (
						<div
							className="handle-height"
							onClick={() => {
								height.current = !open ? null : FormRowHeight * 2 + FormItemRulesHeight;
								setOpen(!open);
							}}
						>
							<Space>
								{open ? '收起选项' : '更多选项'}
								{open ? <UpCircleFilled /> : <DownCircleFilled />}
							</Space>
						</div>
					)}
				</div>
			</div>
		</SearchStyle>
	);
};

export default SearchForm;
